package com.valuegroup.smarttodo.data.service;

import android.text.TextUtils;

import com.valuegroup.smarttodo.data.ServiceFactory;
import com.valuegroup.smarttodo.data.model.AppStatus;
import com.valuegroup.smarttodo.data.model.Event;
import com.valuegroup.smarttodo.data.model.EventDao;
import com.valuegroup.smarttodo.data.model.Goals;
import com.valuegroup.smarttodo.data.model.GoalsDao;
import com.valuegroup.smarttodo.data.vo.GoalQueryParams;
import com.valuegroup.smarttodo.data.vo.GoalsEventVo;
import com.valuegroup.smarttodo.data.vo.GoalsItemVo;
import com.valuegroup.smarttodo.plugins.pickdialog.DateUtils;
import com.valuegroup.smarttodo.util.CollectionUtils;

import org.greenrobot.greendao.query.QueryBuilder;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class GoalsService extends BaseService {

    public List<GoalsItemVo> findGoalForHome(GoalQueryParams p) {
        List<GoalsItemVo> result = new ArrayList<>();

        /*Property type;
        switch (p.getSortType()) {
            case STAR:
                type = GoalsDao.Properties.IsStar;
                break;
            case RANGE:
                type = GoalsDao.Properties.GoalsRange;
                break;
            case FINISH:
                type = GoalsDao.Properties.IsFinish;
                break;
            case ABC:
                type = GoalsDao.Properties.Title;
                break;
            case CREATEDDT:
                type = GoalsDao.Properties.CreatedDt;
                break;
            case NORMAL:
            default:
                type = GoalsDao.Properties.Id;
                break;
        }*/

        QueryBuilder<Goals> q = getGoalsDao().queryBuilder();

        q.where(GoalsDao.Properties.GoalsRange.eq(p.getRange()));
        q.where(GoalsDao.Properties.RangeYear.eq(p.getYear()));
        if (p.getRange() == AppStatus.GoalsRange.MONTHLY) {
            q.where(GoalsDao.Properties.RangeMonthly.eq(p.getMonth()));
        } else if (p.getRange() == AppStatus.GoalsRange.QUARTER) {
            q.where(GoalsDao.Properties.RangeQuarter.eq(p.getQuarter()));
        }

        if (p.isOnlyFinish()) {
            q.where(GoalsDao.Properties.IsFinish.eq(p.isOnlyFinish()));
        }
        if (p.isOnlyUnFinish()) {
            q.where(GoalsDao.Properties.IsFinish.eq(false));
        }

        if (p.isOnlyStar()) {
            q.where(GoalsDao.Properties.IsStar.eq(p.isOnlyStar()));
        }

        /*if (p.isDesc()) {
            q.orderDesc(type);
        } else {
            q.orderAsc(type);
        }*/
        // 已完成排最后，再按名称
        q.orderAsc(GoalsDao.Properties.IsFinish);
        q.orderDesc(GoalsDao.Properties.Title);

        List<Goals> data = q.list();
        for (Goals t : data) {
            GoalsItemVo vo = convertGoalsItemVo(t);
            if (p.isHideFinish()) {
                if (!vo.isShowFinish()) {
                    result.add(vo);
                }
            } else {
                result.add(vo);
            }
        }
        return result;
    }

    public GoalsItemVo convertGoalsItemVo(Goals goal) {
        int finish = 0;

        List<Event> steps = findGoalEvent(goal.getId());
        for (Event s : steps) {
            if (s.getFinish()) {
                finish++;
            }
        }

        GoalsItemVo v = new GoalsItemVo();
        v.setId(goal.getId());

        v.setShowBranch(steps.size() > 0);
        v.setShowStar(goal.getIsStar());
        v.setShowFinish(goal.getIsFinish());
        v.setShowStale(isShowStale(goal));

        v.setLabTitle(goal.getTitle());
        v.setLabBranch(finish + "/" + steps.size());
        v.setLabGrow(0);
        v.setLabRange(getRangeLab(goal));
        v.setLabRangeType(goal.getGoalsRange());
        return v;
    }

    private String getRangeLab(Goals goal) {
        String range = "";
        switch (goal.getGoalsRange()) {
            case AppStatus.GoalsRange.MONTHLY:
                range = goal.getRangeYear() + "年" + goal.getRangeMonthly() + "月份";
                break;
            case AppStatus.GoalsRange.QUARTER:
                range = goal.getRangeYear() + "年" + goal.getRangeQuarter() + "季度";
                break;
            case AppStatus.GoalsRange.YEAR:
                range = goal.getRangeYear() + "年度";
                break;
        }
        return range;
    }

    /**
     * 判断目标是否过期
     *
     * @param goal
     * @return
     */
    private boolean isShowStale(Goals goal) {
        boolean showStale = false;
        Date today = new Date();
        int year = DateUtils.getYear(today);
        int month = DateUtils.getMoth(today);
        int quarter = DateUtils.getQuarter(today);
        if (!goal.getIsFinish()) {
            // 未实现的目标,判断是否过期
            if (year == goal.getRangeYear()) {
                // 同年度分别比较季度和月度
                if (goal.getGoalsRange() == AppStatus.GoalsRange.MONTHLY && goal.getRangeMonthly() < month) {
                    showStale = true;
                } else if (goal.getGoalsRange() == AppStatus.GoalsRange.QUARTER && goal.getRangeQuarter() < quarter) {
                    showStale = true;
                }
            } else if (goal.getRangeYear() < year) {
                showStale = true;
            }
        }
        return showStale;
    }


    public Goals saveGoalTitle(Long id, String title) {
        if (TextUtils.isEmpty(title)) {
            return null;
        }

        if (id == null) {
            Goals target = getDefaultGoals();
            target.setTitle(title);
            getGoalsDao().save(target);
            return target;
        } else {
            Goals t = getGoalsDao().load(id);
            if (t != null && !TextUtils.isEmpty(title) && !t.getTitle().equals(title)) {
                t.setTitle(title);
                t.setUpdatedDt(new Date());
                getGoalsDao().save(t);
            }
            return t;
        }
    }

    public Goals getDefaultGoals() {
        Goals t = new Goals();
        t.setTitle("新目标");
        t.setCreatedDt(new Date());
        t.setUpdatedDt(t.getCreatedDt());
        t.setIsFinish(false);
        t.setFinishDt(null);
        t.setIsPastDue(false);
        t.setIsStar(false);
        t.setRangeYear(DateUtils.getYear(t.getCreatedDt()));
        t.setRangeQuarter(0);
        t.setRangeMonthly(DateUtils.getMoth(t.getCreatedDt()));
        t.setDeadline(DateUtils.setEndTime(DateUtils.getLastDayOfMonth2Date(t.getRangeYear(), t.getRangeMonthly())));
        t.setGoalsRange(AppStatus.GoalsRange.MONTHLY);
        t.setStatus(AppStatus.Status.NORMAL);
        return t;
    }

    public List<GoalsEventVo> findGoalEventForDetail(Long id) {
        List<GoalsEventVo> result = new ArrayList<>();

        List<Event> data = findGoalEvent(id);
        for (Event e : data) {
            result.add(GoalsEventVo.convertEvent(e));
        }

        return result;
    }

    public List<Event> findGoalEvent(Long id) {
        if (id == null) {
            return new ArrayList<>();
        }

        return getEventDao().queryBuilder()
                .where(EventDao.Properties.SourceId.eq(id))
                .where(EventDao.Properties.EventType.gt(AppStatus.EventType.LINE_GOALS))
                .where(EventDao.Properties.EventType.lt(AppStatus.EventType.LINE_GOALS + 10))
                .where(EventDao.Properties.Status.eq(AppStatus.Status.NORMAL))
                .orderAsc(EventDao.Properties.Id)
                .list();
    }


    public GoalsEventVo addGoalEvent(GoalsEventVo item) {
        if (item.getGid() == null) {
            return null;
        }
        Event e = getDefaultEvent(item.getGid());
        e.setTitle(item.getTitle());
        getEventDao().save(e);
        return GoalsEventVo.convertEvent(e);
    }

    public Event getDefaultEvent(Long gid) {
        Goals goals = getGoalsDao().load(gid);

        Event t = new Event();
        t.setTitle("目标事件");
        t.setSourceId(gid);

        setGoalEventType(goals, t);

        t.setPreMinute(25);
        t.setJoinSchedule(false);
        t.setJoinScheduleDt(null);
        t.setScheduleWeekNum(null);
        t.setScheduleDt(null);
        t.setFinish(false);
        t.setFinishDt(null);
        t.setAutoContinue(false);
        t.setCreatedDt(new Date());
        t.setUpdatedDt(t.getCreatedDt());
        t.setStatus(AppStatus.Status.NORMAL);
        return t;
    }

    private void setGoalEventType(Goals goals, Event t) {
        switch (goals.getGoalsRange()) {
            case AppStatus.GoalsRange.MONTHLY:
                t.setEventType(AppStatus.EventType.GOALS_MONTH);
                t.setSourceEndDt(DateUtils.getLastDayOfMonth2Date(goals.getRangeYear(), goals.getRangeMonthly()));
                t.setSourceMonth(goals.getRangeMonthly());
                t.setSourceYear(goals.getRangeYear());
                t.setSourceQuarter(0);
                break;
            case AppStatus.GoalsRange.QUARTER:
                t.setEventType(AppStatus.EventType.GOALS_QUARTER);
                t.setSourceEndDt(DateUtils.getLastDayOfMonth2Date(goals.getRangeYear(), goals.getRangeQuarter() * 3));
                t.setSourceQuarter(goals.getRangeQuarter());
                t.setSourceYear(goals.getRangeYear());
                t.setSourceMonth(0);
                break;
            case AppStatus.GoalsRange.YEAR:
                t.setEventType(AppStatus.EventType.GOALS_YEAR);
                t.setSourceEndDt(DateUtils.getYearLast(goals.getRangeYear()));
                t.setSourceYear(goals.getRangeYear());
                t.setSourceQuarter(0);
                t.setSourceMonth(0);
                break;
        }
    }

    public void delGoal(Long id) {
        Goals t = getGoalsDao().load(id);
        if (t == null) {
            return;
        }

        // 删除事件及相关任务
        List<Event> steps = findGoalEvent(id);
        if (CollectionUtils.isNotEmpty(steps)) {
            for (Event e : steps) {
                ServiceFactory.getInstance().getEventService().delEventTask(e);
                getEventDao().delete(e);
            }
        }

        // 删除标签
        ServiceFactory.getInstance().getTagService().clearTagForGoal(id);
        // 删除关联备注
        ServiceFactory.getInstance().getRemarkService().clearRemark(AppStatus.RemarkType.GOALS, id);

        getGoalsDao().delete(t);
    }

    public GoalsItemVo getGoalsItemVo(long id) {
        if (id == 0) {
            return null;
        }
        return convertGoalsItemVo(getGoalsDao().load(id));
    }

    public void delGoalEvent(Long id) {
        Event e = getEventDao().load(id);
        if (e != null) {
            // 删除关联的任务
            ServiceFactory.getInstance().getEventService().delEventTask(e);

            // 删除事件
            getEventDao().deleteByKey(id);
        }
    }

    public void doStar(Long id, boolean isChecked) {
        if (id == null) {
            return;
        }

        Goals t = getGoalsDao().load(id);
        if (t != null && t.getIsStar() != isChecked) {
            t.setIsStar(isChecked);
            t.setUpdatedDt(new Date());
            getGoalsDao().save(t);
        }
    }

    public void doFinish(Long id, boolean b) {
        if (id == null) {
            return;
        }

        Goals t = getGoalsDao().load(id);
        if (t != null && t.getIsFinish() != b) {

            t.setIsFinish(b);
            t.setFinishDt(b ? new Date() : null);
            t.setUpdatedDt(new Date());

            // 完成时间超过截止日期标记逾期状态
            if (b && DateUtils.compareDate(t.getDeadline(), t.getFinishDt()) < 0) {
                t.setIsPastDue(true);
            }

            getGoalsDao().save(t);
        }
    }


    public Goals saveGoalType(long id,
                              int goalsRange,
                              int rangeYear,
                              int rangeQuarter,
                              int rangeMonthly) {

        Goals t = getGoalsDao().load(id);
        if (t != null) {

            t.setGoalsRange(goalsRange);
            t.setRangeYear(rangeYear);
            t.setRangeQuarter(rangeQuarter);
            t.setRangeMonthly(rangeMonthly);
            t.setUpdatedDt(new Date());

            if (goalsRange == AppStatus.GoalsRange.YEAR) {
                t.setRangeYear(rangeYear);
                t.setRangeQuarter(0);
                t.setRangeMonthly(0);

                // 计算过期时间
                t.setDeadline(DateUtils.setEndTime(DateUtils.getYearLast(t.getRangeYear())));
            } else if (goalsRange == AppStatus.GoalsRange.MONTHLY) {
                t.setRangeMonthly(rangeMonthly);
                t.setRangeQuarter(0);
                t.setDeadline(DateUtils.setEndTime(DateUtils.getLastDayOfMonth2Date(t.getRangeYear(), t.getRangeMonthly())));
            } else if (goalsRange == AppStatus.GoalsRange.QUARTER) {
                t.setRangeQuarter(rangeQuarter);
                t.setRangeMonthly(0);
                t.setDeadline(DateUtils.setEndTime(DateUtils.getLastDayOfMonth2Date(t.getRangeYear(), rangeQuarter * 3)));
            }

            // 完成时间超过截止日期标记逾期状态
            if (t.getIsFinish() && DateUtils.compareDate(t.getDeadline(), t.getFinishDt()) < 0) {
                t.setIsPastDue(true);
            }

            getGoalsDao().save(t);

            // 修改关联的事件
            List<Event> events = findGoalEvent(t.getId());
            for (Event e : events) {
                setGoalEventType(t, e);

                getEventDao().save(e);
            }
        }
        return t;
    }


    public void multiInsert(Long id, String content) {
        if (id == null) {
            return;
        }

        Goals t = getGoalsDao().load(id);
        if (t == null) {
            return;
        }

        String[] arr = content.split("#");
        for (String s : arr) {
            if (!TextUtils.isEmpty(s)) {
                Event e = getDefaultEvent(id);
                e.setTitle(s.trim());
                getEventDao().save(e);
            }
        }
    }

}
